﻿//  Symplectic Spark
//  Copyright 2010 Symplectic Ltd
//  Created by Martyn Whitwell (martyn@symplectic.co.uk)

//  This file is part of Spark.

//  Spark is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.

//  Spark is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.

//  You should have received a copy of the GNU General Public License
//  along with Spark.  If not, see <http://www.gnu.org/licenses/>.

// $URL: https://symplectic-spark.googlecode.com/svn/trunk/website/App_Code/RequestHandler.cs $
// $LastChangedDate: 2010-05-05 14:28:48 +0100 (Wed, 05 May 2010) $
// $LastChangedRevision: 41 $
// $LastChangedBy: martyn@symplectic.co.uk $

using System;
using System.Web;
using System.Web.SessionState;
using System.Threading;
using System.Diagnostics;

namespace Symplectic.Spark
{
    /// <summary>
    /// Summary description for RequestHandler
    /// </summary>
    public class RequestHandler : IHttpHandler, IRequiresSessionState
    {
        public RequestHandler()
        { }

        #region public virtual bool IsReusable
        /// <summary>
        /// We don't wish this instance to be reusable (for a second HTTP request)
        /// </summary>
        public virtual bool IsReusable { get { return false; } }
        #endregion


        public void ProcessRequest(HttpContext context)
        {
            //Start the timer
            Stopwatch timer = null;

            if (Global.DebugMode)
            {
                Global.ClearSettings(); //Clear the components and element definitions                

                timer = new Stopwatch();
                timer.Start();
            }

            context.Response.ContentType = "text/html";
            context.Response.Cache.SetCacheability(HttpCacheability.ServerAndNoCache);
            context.Response.Cache.SetNoStore();
            
            RequestSpec requestSpec;

            try
            {
                requestSpec = new RequestSpec(context.Request);
            }
            catch (Exception ex)
            {
                throw new Exception("Could not process RequestSpec", ex);
            }
            string content;

            //RequestSpec
            try
            {
                //requestSpec = new RequestSpec(context.Request);
                Templater templater = new Templater(requestSpec);
                content = templater.Content;
          
                if (requestSpec.IsError)
                      context.Response.StatusCode = (int)HTTPStatusCode.ServerError;
                else
                      context.Response.StatusCode = (int)HTTPStatusCode.OK;
            }
            catch (ThreadAbortException) { content = "thread aborted"; }
            catch (Exception ex)
            {
                context.Response.StatusCode = (int)HTTPStatusCode.ServerError;
                requestSpec.Exception = ex;
                Templater templater = new Templater(requestSpec, Global.ErrorTemplate);
                content = templater.Content;
            }
                        
            if (Global.DebugMode)
            {
                //Stop the timer
                timer.Stop();
                string debugContent = content.Replace("##debug-render-time##", timer.ElapsedMilliseconds.ToString());
                context.Response.Write(debugContent.Replace("##debug-render-size##", (debugContent.Length / 1024.0).ToString("0.##")));
            }
            else
                context.Response.Write(content);

            context.Response.Flush(); //Using Response.End raises a ThreadAbort error
        }
    }
}